/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pki;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import org.bouncycastle.asn1.x509.KeyUsage;

/**
 *
 * @author Gaetan
 */
public class PKIService {
    
    public final static String basePath = "C:/Documents and Settings/piK/Documents/workspace-sts-2.8.1.RELEASE/netbeans_project/pki/";
    
    public final static String keyStorePath = basePath + "keyStores/";
    public final static String certificatePath = basePath + "certificates/";
    public final static String revocationPath = basePath + "revocations/";
    public final static String keyPath = basePath + "keys/";

    public boolean createCertificate(String algo, Date startDate, Date expiryDate, KeyUsage keyUsage, String alias, String subjectDN, String username, String password, String email) {
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            kst = new KeyStoreTools("JCEKS", password);
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        if(kst.aliasExists(alias)){
            return false;
        }
        
        KeyTools kt = new KeyTools(algo);
        CertificateTools ct = new CertificateTools();
        
        X509Certificate certif = ct.generateCertificate(startDate, expiryDate, kt.getKeyPair(), keyUsage, subjectDN, email);
        
        Certificate[] a = new Certificate[2];
        a[0] = (Certificate) certif;
        a[1] = KeyStoreTools.getCertificateTopLevel();
        
        
        
        
        kst.addCertificate(alias, certif);
        kst.addPrivateKey(alias, kt.getPrivateKey(), password, a);

        kst.saveKeyStore(username, password);
        
        return true;
    }
    
    public boolean writeX509CertificateFile(String username, String password, String alias){
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            return false;
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        
        if(!kst.aliasExists(alias)){
            return false;
        }
        
        X509Certificate cert = (X509Certificate) kst.getCertificate(alias);
        
        CertificateTools ct = new CertificateTools();
        ct.saveX509Certificate(cert, username+"_"+alias);
        
        return true;
    }
    
    public List<X509Certificate> getAllCertificates(String username, String password){
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            return null;
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        
        return kst.getAllCertificates();
    }
    
    public X509Certificate getX509Certificate(String username, String password, String alias){
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            return null;
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        
        if(!kst.aliasExists(alias)){
            return null;
        }
        
        return (X509Certificate) kst.getCertificate(alias);
    }
    
    public boolean writePKCS12CertificateFile(String username, String password, String alias){
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            return false;
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        if(!kst.aliasExists(alias)){
            return false;
        }
        
        KeyStore pkCert = null;
        try{
            pkCert = KeyStore.getInstance("PKCS12");
            pkCert.load(null, null);
        }catch(Exception e){
            return false;
        }
        
        X509Certificate cert = (X509Certificate) kst.getCertificate(alias);
        PrivateKey pKey = kst.getPrivateKey(alias, password);
        
        X509Certificate[] chain = new X509Certificate[2];
        chain[0] = cert;
        chain[1] = KeyStoreTools.getCertificateTopLevel();
        try {
            pkCert.setKeyEntry(alias, pKey, password.toCharArray(), chain);
        } catch (KeyStoreException ex) {
            return false;
        }
        
        CertificateTools ct = new CertificateTools();
        try {
            ct.savePKCS12Certificate(pkCert, username+"_"+alias, password);
        } catch (Exception ex) {
            return false;
        }
        return true;
    }
    
    public boolean writeKeyFile(String username, String password, String alias){
        KeyStoreTools kst = null;
        if(!KeyStoreTools.isKeyStoreExist(username)) {
            return false;
        } else {
            kst = new KeyStoreTools("JCEKS", username, password);
        }
        if(!kst.aliasExists(alias)){
            return false;
        }
        
        PrivateKey pKey = kst.getPrivateKey(alias, password);
        
        KeyTools.saveKeyFile(pKey, username+"_"+alias);
        
        return true;
    }
    
    //-1: période de validité pas encore atteinte, 0: expiré, 1:en cours
    public int isValid(X509Certificate cert){
        Calendar cal = new GregorianCalendar();
        Date now = cal.getTime();
        
        if(cert.getNotBefore().after(now)){
            return -1;
        }else if(cert.getNotAfter().before(now)){
            return 0;
        }
        return 1;
    }
    
    public boolean isRevoked(String username, X509Certificate cert){
        CRLTools crl = new CRLTools(username);
        return new CRLTools(username).isRevoked(cert);
    }
    
    public void revoke(String username, X509Certificate cert, int reason){
        CRLTools crl = new CRLTools(username);
        crl.addRevocation(cert, reason);
        crl.write();
    }
    
    public List<X509CRLEntry> getRevocationList(String username){
        CRLTools crl = new CRLTools(username);
        return crl.getRevocationList();
    }
    
    
    
}